package pub.tbc.rubbish.client.registry.impl;

import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;
import pub.tbc.rubbish.client.Constant;
import pub.tbc.rubbish.client.registry.Registry;
import pub.tbc.rubbish.client.util.ZkHelper;
import pub.tbc.toolkit.Objs;
import pub.tbc.toolkit.PropsUtil;

import java.util.List;

/**
 * 使用zookeeper（curator framework）进行注册
 *
 * @author tbc on 2016/12/7 09:48:55.
 */
@Slf4j
public class ZKRegistry implements Registry {

    @Override
    public void register(String serviceName, String serviceAddress) {
        try {
            String registryPath = PropsUtil.getString(
                    PropsUtil.load(Constant.DEFAULT_CONFIG_FILE),
                    Constant.REGISTRY_NODE,
                    Constant.DEFAULT_REGISTRY_NODE
            );

            // init zk client
            CuratorFramework client = ZkHelper.getCuratorFrameworkWithOptions();
            //client.start();

            // 创建服务注册根节点（永久节点），用于存储服务注册信息
            if (client.checkExists().forPath(registryPath) == null) {
                String s = client.create()                      //创建一个路径
                        .creatingParentsIfNeeded()              //如果指定的节点的父节点不存在，递归创建父节点
                        .withMode(CreateMode.PERSISTENT)        //存储类型（临时的还是持久的）
                        .withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)   //访问权限
                        .forPath(registryPath);                 //创建的路径
            }

            // 创建服务节点（持久节点）- 可以与上一步合并创建，不过分开感觉清晰点
            String servicePath = registryPath + "/" + serviceName;
            if (Objs.isEmpty(client.checkExists().forPath(servicePath))) {
                client.create().creatingParentsIfNeeded()
                        .withMode(CreateMode.PERSISTENT)
                        .withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)
                        .forPath(servicePath);
            }

            // 创建地址节点（临时节点）
            String addressPath = servicePath + "/" + serviceAddress;
            if (Objs.isEmpty(client.checkExists().forPath(addressPath))) {
                client.create().withMode(CreateMode.EPHEMERAL)
                        .withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)
                        .forPath(addressPath);
            }

            List<String> addresses = client.getChildren().forPath(servicePath);
            log.info("服务节点 {} 下地址列表：{}", servicePath, addresses);

            // 设置初始权重
            // client.setData().forPath(serviceDataNode, "".getBytes());

        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }

    }

}
